<?php

namespace WenRuns\Laravel;

use App\Http\Kernel;
use Encore\Admin\Form;
use Encore\Admin\Layout\Content;
use Illuminate\Routing\Router;
use Illuminate\Support\Arr;
use Illuminate\Support\ServiceProvider;
use WenRuns\Laravel\Admin\Form\Field\ApiSelect;
use WenRuns\Laravel\Admin\Form\Field\CheckboxTree;
use WenRuns\Laravel\Admin\Form\Field\ExcelSheet;
use WenRuns\Laravel\Admin\Form\Field\Grid\Grid;
use WenRuns\Laravel\Admin\Form\Field\InputSelect;
use WenRuns\Laravel\Admin\Form\Field\MultiCheckbox;
use WenRuns\Laravel\Admin\Form\Field\MultiList\MultiList;
use WenRuns\Laravel\Admin\Form\Field\Tabs;
use WenRuns\Laravel\Http\Middleware\GridForm;
use WenRuns\Laravel\Http\Middleware\Permission;


class LaravelServiceProvider extends ServiceProvider
{
    protected $commands = [

    ];

    protected $middleware = [
        GridForm::class,
    ];

    protected $routeMiddleware = [
        'admin.permission' => Permission::class,
    ];

    protected $middlewareGroups = [

    ];

    /**
     * {@inheritdoc}
     */
    public function boot(Laravel $extension)
    {
        if (!Laravel::boot()) {
            return;
        }

        $this->publishes([
            __DIR__ . '/../config/wenruns_laravel_service.php' => config_path('wenruns_laravel_service.php'),
        ]);

        if ($views = $extension->views()) {
            $this->loadViewsFrom($views, 'WenRuns');
            $this->loadViewsFrom($views . '/admin', 'WenAdmin');
        }

        if ($this->app->runningInConsole() && $assets = $extension->assets()) {
            $this->publishes(
                [$assets => public_path(trim(Laravel::$assetLoadRoot, '/'))],
                'laravel-service'
            );
        }

        $this->app->booted(function () {
            Laravel::routes(__DIR__ . '/../routes/web.php');
        });

        $this->handle();
    }


    public function handle()
    {
        Form::extend('multiList', MultiList::class);
        Form::extend('wenTab', Tabs::class);
        Form::extend('apiSelect', ApiSelect::class);
        Form::extend('checkboxTree', CheckboxTree::class);
        Form::extend('inputSelect', InputSelect::class);
        Form::extend('multiCheckbox', MultiCheckbox::class);
        Form::extend('excelSheet', ExcelSheet::class);
        Form::extend('grid', Grid::class);
    }

    public function register()
    {
        $this->loadConfig();
        $this->registerRouteMiddleware();
        $this->commands($this->commands);
        $this->macroRouter();
    }

    /**
     * Extends laravel router.
     */
    protected function macroRouter()
    {
        Router::macro('content', function ($uri, $content, $options = []) {
            return $this->match(['GET', 'HEAD'], $uri, function (Content $layout) use ($content, $options) {
                return $layout
                    ->title(Arr::get($options, 'title', ' '))
                    ->description(Arr::get($options, 'desc', ' '))
                    ->body($content);
            });
        });

        Router::macro('component', function ($uri, $component, $data = [], $options = []) {
            return $this->match(['GET', 'HEAD'], $uri, function (Content $layout) use ($component, $data, $options) {
                return $layout
                    ->title(Arr::get($options, 'title', ' '))
                    ->description(Arr::get($options, 'desc', ' '))
                    ->component($component, $data);
            });
        });
    }

    /**
     *
     */
    protected function loadConfig()
    {
        $this->mergeConfigFrom(
            __DIR__ . '/../config/wenruns_laravel_service.php', 'wenruns_laravel_service'
        );
    }

    /**
     * Register the route middleware.
     *
     * @return void
     */
    protected function registerRouteMiddleware()
    {
        /** @var Kernel $kernel */
        $kernel = app(\Illuminate\Contracts\Http\Kernel::class);
        foreach ($this->middleware as $item) {
            $kernel->prependMiddleware($item);
        }
        /** @var Router $router */
        $router = app('router');
        // register route middleware.
        foreach ($this->routeMiddleware as $key => $middleware) {
            $router->aliasMiddleware($key, $middleware);
        }

        // register middleware group.
        foreach ($this->middlewareGroups as $key => $middleware) {
            $router->middlewareGroup($key, $middleware);
        }
    }
}
